﻿Shader "Dan/2D/UberParticles"
{
    Properties
    {
        //main
        [Header(Main)]
        _TintColor ("Tint Color", Color) = (0.5, 0.5, 0.5, 0.5)
        _MainTex ("Main Tex", 2D) = "white" { }
        
        //uv flow
        [Header(UV Flow)]
        [Toggle(USE_UV_FLOW)] _UseUVFlow ("Use UV Flow", Int) = 0
        _FlowSpeedX ("Flow Speed X", Float) = 0.5
        _FlowSpeedY ("Flow Speed Y", Float) = 0.5
        
        //uv mask
        [Header(UV Mask)]
        //[Toggle(USE_UV_MASK)] _UseUVMASK ("Use UV Mask", Int) = 0
        _MaskTex ("Mask Tex", 2D) = "white" { }
        
        
        //distort
        [Header(Distort)]
        //[Toggle(USE_DISTORT)]_UseDistort ("Use Distort", Int) =0
        _DistortTex ("Distort Tex", 2D) = "bump" { }
        _DistrotStrength ("Distrot Strength", Range(0, 0.5)) = 0
        _DistortRotateSpeed ("Distort Rotate Speed", Float) = 0
        
        //dissolve
        [Header(Dissolve)]
        //[Toggle(USE_DISSOLVE)]_UseDissolve ("Use Dissolve", Int) =0
        _DissolveTex ("Dissolve Tex", 2D) = "white" { }
        _DissolveProgress ("Dissolve Progress", Range(0, 1)) = 0
        [HDR]_DissolveColor ("Dissolve Color", Color) = (0.5, 0.5, 0.5, 0.5)
        _DissolveRange ("Dissolve Range", Range(0, 1)) = 0
        
        //soft particles
        [Header(Soft Particles)]
        [Toggle(USE_SOFT_PARTICLES)]_UseSoftParticle ("Use Soft Particle", Int) = 0
        _InvFade ("Soft Particles Factor", Range(0.01, 3.0)) = 1.0
        
        [Space]
        [Header(Rendering)]
        [Enum(Cull Off, 0, Cull Front, 1, Cull Back, 2)]
        _CullMode ("Culling", Float) = 0 //0 = off, 2=back
        [KeywordEnum(Additive, Blend, Opaque, Cutout, Transparent, Subtractive, Modulate)]
        _BlendMode ("Blend Mode", Float) = 1
        _SrcBlend ("SrcBlend", Int) = 5
        _DstBlend ("DstBlend", Int) = 10
        [HideInInspector] _BlendOp ("_blendop", Float) = 0.0
        _ZWrite ("ZWrite On", Int) = 1
    }
    
    
    Category
    {
        SubShader
        {
            LOD 0
            
            Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
            BlendOp [_BlendOp]
            Blend[_SrcBlend][_DstBlend]
            Cull[_CullMode]
            ZWrite[_ZWrite]
            Lighting Off
            ColorMask RGB
            
            Pass
            {
                
                CGPROGRAM
                
                #pragma vertex vert
                #pragma fragment frag
                #pragma target 2.0
                #pragma shader_feature USE_SOFT_PARTICLES
                #pragma shader_feature USE_UV_FLOW
                #pragma shader_feature USE_UV_MASK
                #pragma shader_feature USE_DISTORT
                #pragma shader_feature USE_DISSOLVE
                
                #include "UnityCG.cginc"
               
                //#define USE_SOFT_PARTICLES
                #if defined(USE_SOFT_PARTICLES) || defined(SOFTPARTICLES_ON)
                    #define USING_SOFT_PARTICLES
                #endif
                
                //#define USE_UV_FLOW
                #if defined(USE_UV_FLOW)
                    #define USING_UV_FLOW
                #endif
                
                //#define USE_UV_MASK
                #if defined(USE_UV_MASK)
                    #define USING_UV_MASK
                #endif
                //#define USE_DISTORT
                #if defined(USE_DISTORT)
                    #define USING_DISTORT
                #endif
                //#define USE_DISSOLVE
                #if defined(USE_DISSOLVE)
                    #define USING_DISSOLVE
                #endif
                
                struct appdata_t
                {
                    float4 vertex: POSITION;
                    fixed4 color: COLOR;
                    float4 uv: TEXCOORD0;
                };
                
                struct v2f
                {
                    float4 vertex: SV_POSITION;
                    fixed4 color: COLOR;
                    float4 uv: TEXCOORD0;
                    UNITY_FOG_COORDS(1)
                    #ifdef USING_SOFT_PARTICLES
                        float4 projPos: TEXCOORD2;
                    #endif
                };
                
                #ifdef USING_SOFT_PARTICLES
                    uniform float _InvFade;
                    #if UNITY_VERSION >= 560
                        UNITY_DECLARE_DEPTH_TEXTURE(_CameraDepthTexture);
                    #else
                        uniform sampler2D_float _CameraDepthTexture;
                    #endif
                #endif //USING_SOFT_PARTICLES
                
                #ifdef USING_UV_FLOW
                    float _FlowSpeedX;
                    float _FlowSpeedY;
                #endif //USING_UV_FLOW
                
                #ifdef USING_UV_MASK
                    sampler2D _MaskTex;
                #endif //USING_UV_MASK
                
                #ifdef USING_DISTORT
                    sampler2D _DistortTex;
                    float4 _DistortTex_ST;
                    float _DistrotStrength;
                    float _DistortRotateSpeed;
                #endif //USING_DISTORT
                
                #ifdef USING_DISSOLVE
                    sampler2D _DissolveTex;
                    float4 _DissolveTex_ST;
                    float  _DissolveProgress;
                    fixed4 _DissolveColor;
                    float _DissolveRange;
                #endif //USING_DISSOLVE
                
                
                sampler2D _MainTex;
                fixed4 _TintColor;
                float4 _MainTex_ST;
                
                
                
                v2f vert(appdata_t v)
                {
                    v2f o;
                    v.vertex.xyz += float3(0, 0, 0) ;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    #ifdef USING_SOFT_PARTICLES
                        o.projPos = ComputeScreenPos(o.vertex);
                        COMPUTE_EYEDEPTH(o.projPos.z);
                    #endif//USING_SOFT_PARTICLES
                    o.color = v.color;
                    o.uv = v.uv;
                    
                    return o;
                }
                float2 Rotate2D_Rad(float2 uv, float2 center, float rad)
                {
                    uv -= center;
                    float2x2 m = float2x2(cos(rad), sin(rad), -sin(rad), cos(rad));
                    uv = mul(m, uv) + center;
                    return uv;
                }
                fixed4 frag(v2f i): SV_Target
                {
                    
                    
                    //soft particles
                    #ifdef USING_SOFT_PARTICLES
                        float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos)));
                        float partZ = i.projPos.z;
                        float fade = saturate(_InvFade * (sceneZ - partZ));
                        i.color.a *= fade;
                    #endif//USING_SOFT_PARTICLES
                    
                    //main uv
                    float2 uv = TRANSFORM_TEX(i.uv.xy, _MainTex);
                    
                    
                    
                    //uv mask
                    float mask = 1;
                    #ifdef USING_UV_MASK
                        mask = tex2D(_MaskTex, uv).r;
                    #endif//USING_UV_MASK
                    
                    //distort
                    #ifdef USING_DISTORT
                        float2 distortUV = TRANSFORM_TEX(uv, _DistortTex);
                        float2 distortVal = UnpackNormal(tex2D(_DistortTex, distortUV)).rg;
                        uv += distortVal * _DistrotStrength;
                        float r = _Time.y * _DistortRotateSpeed;
                        uv = Rotate2D_Rad(uv, 0.5, r);
                    #endif//USING_DISTORT
                    
                    //uv flow
                    #ifdef USING_UV_FLOW
                        uv.x -= _Time.y * _FlowSpeedX;
                        uv.y -= _Time.y * _FlowSpeedY;
                    #endif //USING_UV_FLOW
                    
                    
                    float4 mainColor = tex2D(_MainTex, uv);
                    
                    
                    #ifdef USING_DISSOLVE
                        float customData = i.uv.z;
                        float2 dissolveUV = TRANSFORM_TEX(uv, _DissolveTex);
                        float a = tex2D(_DissolveTex, dissolveUV).r * mainColor.a;
                        float b = customData + _DissolveProgress + 0.01;
                        float dissolveVal = a - b;
                        clip(dissolveVal);
                        
                        float dissolveEdge = saturate(dissolveVal * 4);
                        dissolveEdge = smoothstep(0, _DissolveRange, dissolveEdge);
                        mainColor = lerp(_DissolveColor * mainColor, mainColor, dissolveEdge);
                    #endif//USING_DISSOLVE
                    
                    fixed4 col = 2.0f * i.color * mask * _TintColor * mainColor ;
                    
                    return col;
                }
                ENDCG
                
            }//Pass
        }//SubShader
    }//Category
    CustomEditor "Dan.ParticleGUI"
}
